<template>
  <div class="app-container">
    <el-card class="page-container">
      <template #header>
        <div class="card-header">
          <h3>预览生成</h3>
          <div class="header-actions">
            <el-button type="info" @click="handleConfigGenerate">
              <el-icon><Setting /></el-icon>
              生成配置
            </el-button>
            <el-button type="success" @click="handleGenerateAll">
              <el-icon><Download /></el-icon>
              生成全部
            </el-button>
          </div>
        </div>
      </template>

      <!-- 生成配置卡片 -->
      <el-card class="config-card" shadow="never">
        <template #header>
          <div class="config-header">
            <h4>项目配置</h4>
            <el-tag type="primary">
              {{ generateConfig.version }}
            </el-tag>
          </div>
        </template>

        <div class="config-info">
          <el-descriptions :column="2" border>
            <el-descriptions-item label="项目名称">
              {{ generateConfig.projectName }}
            </el-descriptions-item>
            <el-descriptions-item label="基础路径">
              <el-text type="primary">
                {{ generateConfig.basePath }}
              </el-text>
            </el-descriptions-item>
            <el-descriptions-item label="作者">
              {{ generateConfig.author }}
            </el-descriptions-item>
            <el-descriptions-item label="生成类型">
              <el-tag
                v-for="type in generateConfig.generateTypes"
                :key="type"
                :type="getGenerateTypeColor(type)"
                style="margin-right: 5px;"
              >
                {{ getGenerateTypeName(type) }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="项目描述" :span="2">
              {{ generateConfig.description }}
            </el-descriptions-item>
          </el-descriptions>
        </div>
      </el-card>

      <!-- 统计信息 -->
      <el-row :gutter="20" class="stats-row">
        <el-col :span="6">
          <el-card class="stats-card" shadow="hover">
            <el-statistic title="数据表数量" :value="tables.length">
              <template #prefix>
                <el-icon style="vertical-align: middle;">
                  <Grid />
                </el-icon>
              </template>
            </el-statistic>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card class="stats-card" shadow="hover">
            <el-statistic title="接口数量" :value="apiEndpoints.length">
              <template #prefix>
                <el-icon style="vertical-align: middle;">
                  <Connection />
                </el-icon>
              </template>
            </el-statistic>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card class="stats-card" shadow="hover">
            <el-statistic title="关联关系" :value="totalRelations">
              <template #prefix>
                <el-icon style="vertical-align: middle;">
                  <Share />
                </el-icon>
              </template>
            </el-statistic>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card class="stats-card" shadow="hover">
            <el-statistic title="字段总数" :value="totalFields">
              <template #prefix>
                <el-icon style="vertical-align: middle;">
                  <List />
                </el-icon>
              </template>
            </el-statistic>
          </el-card>
        </el-col>
      </el-row>

      <!-- 生成选项 -->
      <el-card class="generate-card" shadow="never">
        <template #header>
          <h4>生成选项</h4>
        </template>

        <el-row :gutter="20">
          <el-col :span="8">
            <el-card
              class="generate-option-card"
              :class="{ active: selectedGenerateTypes.includes('swagger') }"
              shadow="hover"
              @click="toggleGenerateType('swagger')"
            >
              <div class="option-content">
                <div class="option-icon">
                  <el-icon size="32" color="#52c41a">
                    <Document />
                  </el-icon>
                </div>
                <div class="option-info">
                  <h5>Swagger 文档</h5>
                  <p>生成 OpenAPI 3.0 规范的接口文档</p>
                  <el-tag v-if="selectedGenerateTypes.includes('swagger')" type="success" size="small">
                    已选择
                  </el-tag>
                </div>
              </div>
            </el-card>
          </el-col>

          <el-col :span="8">
            <el-card
              class="generate-option-card"
              :class="{ active: selectedGenerateTypes.includes('typescript') }"
              shadow="hover"
              @click="toggleGenerateType('typescript')"
            >
              <div class="option-content">
                <div class="option-icon">
                  <el-icon size="32" color="#1890ff">
                    <Files />
                  </el-icon>
                </div>
                <div class="option-info">
                  <h5>TypeScript 类型</h5>
                  <p>生成前端 TypeScript 接口定义</p>
                  <el-tag v-if="selectedGenerateTypes.includes('typescript')" type="primary" size="small">
                    已选择
                  </el-tag>
                </div>
              </div>
            </el-card>
          </el-col>

          <el-col :span="8">
            <el-card
              class="generate-option-card"
              :class="{ active: selectedGenerateTypes.includes('mock') }"
              shadow="hover"
              @click="toggleGenerateType('mock')"
            >
              <div class="option-content">
                <div class="option-icon">
                  <el-icon size="32" color="#faad14">
                    <DataAnalysis />
                  </el-icon>
                </div>
                <div class="option-info">
                  <h5>Mock 数据</h5>
                  <p>生成模拟数据和 Mock 服务</p>
                  <el-tag v-if="selectedGenerateTypes.includes('mock')" type="warning" size="small">
                    已选择
                  </el-tag>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </el-card>

      <!-- 预览区域 -->
      <el-card class="preview-card" shadow="never">
        <template #header>
          <div class="preview-header">
            <h4>生成预览</h4>
            <div class="preview-actions">
              <el-radio-group v-model="previewType" size="small">
                <el-radio-button label="swagger">
                  Swagger
                </el-radio-button>
                <el-radio-button label="typescript">
                  TypeScript
                </el-radio-button>
                <el-radio-button label="mock">
                  Mock Data
                </el-radio-button>
              </el-radio-group>
              <el-button type="primary" size="small" @click="handlePreview">
                <el-icon><View /></el-icon>
                刷新预览
              </el-button>
            </div>
          </div>
        </template>

        <div class="preview-content">
          <el-scrollbar height="500px">
            <pre class="code-preview"><code>{{ previewContent }}</code></pre>
          </el-scrollbar>
        </div>
      </el-card>
    </el-card>

    <!-- 生成配置对话框 -->
    <el-dialog
      v-model="configDialogVisible"
      title="生成配置"
      width="600px"
      :close-on-click-modal="false"
      class="config-dialog"
    >
      <el-form
        ref="configFormRef"
        :model="configForm"
        :rules="configFormRules"
        label-width="100px"
      >
        <el-form-item label="项目名称" prop="projectName">
          <el-input v-model="configForm.projectName" placeholder="请输入项目名称" />
        </el-form-item>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="版本号" prop="version">
              <el-input v-model="configForm.version" placeholder="1.0.0" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="基础路径" prop="basePath">
              <el-input v-model="configForm.basePath" placeholder="/api/v1" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="作者" prop="author">
          <el-input v-model="configForm.author" placeholder="请输入作者名称" />
        </el-form-item>

        <el-form-item label="项目描述">
          <el-input
            v-model="configForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入项目描述"
          />
        </el-form-item>

        <el-form-item label="生成类型">
          <el-checkbox-group v-model="configForm.generateTypes">
            <el-checkbox label="swagger">
              Swagger 文档
            </el-checkbox>
            <el-checkbox label="typescript">
              TypeScript 类型
            </el-checkbox>
            <el-checkbox label="mock">
              Mock 数据
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="configDialogVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="handleSaveConfig">
          保存配置
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import type { ApiEndpoint, DataTable, GenerateConfig } from "../types"
import {
  Connection,
  DataAnalysis,
  Document,
  Download,
  Files,
  Grid,
  List,
  Setting,
  Share,
  View
} from "@element-plus/icons-vue"
import { ElMessage } from "element-plus"
import { computed, onMounted, reactive, ref } from "vue"
import { mockApiEndpoints, mockGenerateConfig, mockTables } from "../mock/data"

// 响应式数据
const tables = ref<DataTable[]>([])
const apiEndpoints = ref<ApiEndpoint[]>([])
const generateConfig = ref<GenerateConfig>({ ...mockGenerateConfig })
const configDialogVisible = ref(false)
const selectedGenerateTypes = ref<string[]>(["swagger", "typescript", "mock"])
const previewType = ref("swagger")
const previewContent = ref("")

// 配置表单
const configForm = reactive({
  projectName: "",
  version: "",
  basePath: "",
  author: "",
  description: "",
  generateTypes: [] as string[]
})

// 表单验证规则
const configFormRules = {
  projectName: [
    { required: true, message: "请输入项目名称", trigger: "blur" }
  ],
  version: [
    { required: true, message: "请输入版本号", trigger: "blur" }
  ],
  basePath: [
    { required: true, message: "请输入基础路径", trigger: "blur" }
  ],
  author: [
    { required: true, message: "请输入作者名称", trigger: "blur" }
  ]
}

// 表单引用
const configFormRef = ref()

// 计算属性
const totalRelations = computed(() => {
  return tables.value.reduce((total: number, table: DataTable) => {
    return total + table.fields.filter((field: any) => field.relation?.enabled).length
  }, 0)
})

const totalFields = computed(() => {
  return tables.value.reduce((total: number, table: DataTable) => total + table.fields.length, 0)
})

// 方法
function loadData() {
  tables.value = [...mockTables]
  apiEndpoints.value = [...mockApiEndpoints]
  generatePreview()
}

function getGenerateTypeColor(type: string): string {
  const colorMap: Record<string, string> = {
    swagger: "success",
    typescript: "primary",
    mock: "warning"
  }
  return colorMap[type] || "info"
}

function getGenerateTypeName(type: string): string {
  const nameMap: Record<string, string> = {
    swagger: "Swagger 文档",
    typescript: "TypeScript 类型",
    mock: "Mock 数据"
  }
  return nameMap[type] || type
}

function toggleGenerateType(type: string) {
  const index = selectedGenerateTypes.value.indexOf(type)
  if (index > -1) {
    selectedGenerateTypes.value.splice(index, 1)
  } else {
    selectedGenerateTypes.value.push(type)
  }
}

function handleConfigGenerate() {
  configDialogVisible.value = true

  // 填充表单数据
  configForm.projectName = generateConfig.value.projectName
  configForm.version = generateConfig.value.version
  configForm.basePath = generateConfig.value.basePath
  configForm.author = generateConfig.value.author
  configForm.description = generateConfig.value.description
  configForm.generateTypes = [...generateConfig.value.generateTypes]
}

async function handleSaveConfig() {
  try {
    await configFormRef.value?.validate()

    // 更新生成配置
    Object.assign(generateConfig.value, {
      projectName: configForm.projectName,
      version: configForm.version,
      basePath: configForm.basePath,
      author: configForm.author,
      description: configForm.description,
      generateTypes: [...configForm.generateTypes]
    })

    ElMessage.success("配置保存成功")
    configDialogVisible.value = false
    generatePreview()
  } catch (error) {
    console.error("配置表单验证失败:", error)
  }
}

function handlePreview() {
  generatePreview()
}

function generatePreview() {
  switch (previewType.value) {
    case "swagger":
      previewContent.value = generateSwaggerPreview()
      break
    case "typescript":
      previewContent.value = generateTypeScriptPreview()
      break
    case "mock":
      previewContent.value = generateMockPreview()
      break
  }
}

function generateSwaggerPreview(): string {
  const swagger = {
    openapi: "3.0.0",
    info: {
      title: generateConfig.value.projectName,
      version: generateConfig.value.version,
      description: generateConfig.value.description,
      contact: {
        name: generateConfig.value.author
      }
    },
    servers: [
      {
        url: generateConfig.value.basePath,
        description: "API 服务器"
      }
    ],
    paths: {},
    components: {
      schemas: {}
    }
  }

  // 生成路径和模型
  apiEndpoints.value.forEach((api: ApiEndpoint) => {
    const path = api.path.replace(generateConfig.value.basePath, "")
    if (!(swagger.paths as any)[path]) {
      (swagger.paths as any)[path] = {}
    }

    (swagger.paths as any)[path][api.method.toLowerCase()] = {
      summary: api.name,
      description: api.description || api.name,
      tags: [api.tableName],
      parameters: api.queryFields
        .filter((field: any) => field.enabled)
        .map((field: any) => ({
          name: field.fieldName,
          in: "query",
          required: field.required,
          schema: {
            type: getSwaggerType(field.fieldName)
          }
        })),
      responses: {
        200: {
          description: "成功",
          content: {
            "application/json": {
              schema: {
                type: "object",
                properties: {
                  code: { type: "integer" },
                  message: { type: "string" },
                  data: {
                    type: "object",
                    properties: api.responseFields
                      .filter((field: any) => field.enabled)
                      .reduce((props: any, field: any) => {
                        props[field.alias || field.fieldName] = {
                          type: getSwaggerType(field.fieldName)
                        }
                        return props
                      }, {} as any)
                  }
                }
              }
            }
          }
        }
      }
    }
  })

  return JSON.stringify(swagger, null, 2)
}

function generateTypeScriptPreview(): string {
  let code = `// ${generateConfig.value.projectName} - TypeScript 类型定义\n`
  code += `// 版本: ${generateConfig.value.version}\n`
  code += `// 作者: ${generateConfig.value.author}\n\n`

  // 生成接口类型
  tables.value.forEach((table: DataTable) => {
    code += `/** ${table.comment} */\n`
    code += `export interface ${pascalCase(table.name)} {\n`

    table.fields.forEach((field: any) => {
      const optional = field.required ? "" : "?"
      const tsType = getTypeScriptType(field.type)
      code += `  /** ${field.comment} */\n`
      code += `  ${field.name}${optional}: ${tsType}\n`
    })

    code += `}\n\n`
  })

  // 生成API函数类型
  apiEndpoints.value.forEach((api: ApiEndpoint) => {
    const queryParams = api.queryFields.filter((f: any) => f.enabled)
    if (queryParams.length > 0) {
      code += `/** ${api.name} - 查询参数 */\n`
      code += `export interface ${pascalCase(api.id)}Params {\n`
      queryParams.forEach((param: any) => {
        const optional = param.required ? "" : "?"
        code += `  ${param.fieldName}${optional}: ${getTypeScriptType(param.fieldName)}\n`
      })
      code += `}\n\n`
    }

    code += `/** ${api.name} - 响应数据 */\n`
    code += `export interface ${pascalCase(api.id)}Response {\n`
    api.responseFields.filter((f: any) => f.enabled).forEach((field: any) => {
      const fieldName = field.alias || field.fieldName
      code += `  ${fieldName}: ${getTypeScriptType(field.fieldName)}\n`
    })
    code += `}\n\n`
  })

  return code
}

function generateMockPreview(): string {
  let code = `// ${generateConfig.value.projectName} - Mock 数据\n`
  code += `// 版本: ${generateConfig.value.version}\n\n`

  code += `import { MockMethod } from 'vite-plugin-mock'\n\n`
  code += `export default [\n`

  apiEndpoints.value.forEach((api: ApiEndpoint, index: number) => {
    code += `  {\n`
    code += `    url: '${generateConfig.value.basePath}${api.path}',\n`
    code += `    method: '${api.method.toLowerCase()}',\n`
    code += `    response: () => {\n`
    code += `      return {\n`
    code += `        code: 0,\n`
    code += `        message: '成功',\n`
    code += `        data: {\n`

    api.responseFields.filter((f: any) => f.enabled).forEach((field: any) => {
      const fieldName = field.alias || field.fieldName
      const mockValue = getMockValue(field.fieldName)
      code += `          ${fieldName}: ${mockValue},\n`
    })

    code += `        }\n`
    code += `      }\n`
    code += `    }\n`
    code += `  }${index < apiEndpoints.value.length - 1 ? "," : ""}\n`
  })

  code += `] as MockMethod[]\n`

  return code
}

function getSwaggerType(fieldName: string): string {
  if (fieldName.includes("id") || fieldName.includes("count")) return "integer"
  if (fieldName.includes("amount") || fieldName.includes("price")) return "number"
  if (fieldName.includes("status") || fieldName.includes("enabled")) return "boolean"
  if (fieldName.includes("time") || fieldName.includes("date")) return "string"
  return "string"
}

function getTypeScriptType(fieldName: string): string {
  if (fieldName.includes("id") || fieldName.includes("count")) return "number"
  if (fieldName.includes("amount") || fieldName.includes("price")) return "number"
  if (fieldName.includes("status") || fieldName.includes("enabled")) return "boolean"
  if (fieldName.includes("time") || fieldName.includes("date")) return "string"
  return "string"
}

function getMockValue(fieldName: string): string {
  if (fieldName.includes("id")) return "1"
  if (fieldName.includes("name")) return "\"示例名称\""
  if (fieldName.includes("email")) return "\"example@email.com\""
  if (fieldName.includes("phone")) return "\"13800138000\""
  if (fieldName.includes("status")) return "true"
  if (fieldName.includes("time") || fieldName.includes("date")) return "\"2025-01-01 12:00:00\""
  if (fieldName.includes("count") || fieldName.includes("amount")) return "100"
  return "\"示例值\""
}

function pascalCase(str: string): string {
  return str.replace(/(?:^|[_-])([a-z])/g, (_: any, char: string) => char.toUpperCase())
}

function handleGenerateAll() {
  if (selectedGenerateTypes.value.length === 0) {
    ElMessage.warning("请至少选择一种生成类型")
    return
  }

  ElMessage.success(`正在生成 ${selectedGenerateTypes.value.map((t: string) => getGenerateTypeName(t)).join("、")}...`)

  // 这里可以实现实际的文件生成和下载逻辑
  setTimeout(() => {
    ElMessage.success("生成完成！")
  }, 2000)
}

// 监听预览类型变化
function _handlePreviewTypeChange() {
  generatePreview()
}

// 生命周期
onMounted(() => {
  loadData()
})
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.page-container {
  min-height: calc(100vh - 120px);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header h3 {
  margin: 0;
  color: #303133;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.config-card {
  margin-bottom: 20px;
}

.config-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.config-header h4 {
  margin: 0;
  color: #303133;
}

.config-info {
  padding: 10px 0;
}

.stats-row {
  margin-bottom: 20px;
}

.stats-card {
  text-align: center;
  transition: transform 0.3s ease;
}

.stats-card:hover {
  transform: translateY(-2px);
}

.generate-card {
  margin-bottom: 20px;
}

.generate-card h4 {
  margin: 0;
  color: #303133;
}

.generate-option-card {
  cursor: pointer;
  transition: all 0.3s ease;
  height: 120px;
  display: flex;
  align-items: center;
}

.generate-option-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.generate-option-card.active {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}

.option-content {
  display: flex;
  align-items: center;
  gap: 15px;
  width: 100%;
}

.option-icon {
  flex-shrink: 0;
}

.option-info h5 {
  margin: 0 0 8px 0;
  color: #303133;
  font-size: 16px;
}

.option-info p {
  margin: 0 0 8px 0;
  color: #606266;
  font-size: 14px;
}

.preview-card {
  margin-bottom: 20px;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.preview-header h4 {
  margin: 0;
  color: #303133;
}

.preview-actions {
  display: flex;
  align-items: center;
  gap: 15px;
}

.preview-content {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 10px;
}

.code-preview {
  font-family: "Courier New", Monaco, monospace;
  font-size: 13px;
  line-height: 1.5;
  color: #24292e;
  background: transparent;
  white-space: pre-wrap;
  word-wrap: break-word;
}

:deep(.el-statistic__content) {
  font-size: 24px;
  font-weight: 600;
}

:deep(.el-statistic__title) {
  font-size: 14px;
  color: #606266;
}

/* 弹出框样式隔离 */
:deep(.config-dialog .el-dialog__body) {
  padding: 20px;
}

:deep(.config-dialog .el-form-item__label) {
  font-weight: 500;
  color: #303133;
}
</style>
